#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <errno.h>
#include <linux/input.h>
#include<stdlib.h>
#include <pthread.h>
#include <stdlib.h>
 
int fd_lcd;
int *map_lcd;
int fd_ts;
int x,y;
int res;//管道创建返回值 0成功
int fifo;//打开管道的文件
struct dirent **namelist;	//指向结构体dirent指针的指针变量 namelist
int liu = 0;//判断下一首用到
int fu = 0;//判断下一首用到
char name[500];//存储文件名字
int n;
int flag;

//自定义"*.avi"文件筛选回调函数
int myfilter_mp3(const struct dirent *filename) //输入文件目录 .
{
    size_t len;
    len = strlen(filename->d_name);  //strlen（）获取字符串长度
    if (len >= 4
        && filename->d_name[len - 4] == '.'
        && filename->d_name[len - 3] == 'a'
		&& filename->d_name[len - 2] == 'v'
        && filename->d_name[len - 1] == 'i')
        return 1;
 
    return 0;
}

int lcd_init()
{
	//打开LCD的设备文件
	fd_lcd = open("/dev/fb0",O_RDWR);
	if(-1 == fd_lcd)
	{
		perror("open LCD failed:");
		return -1;
	}
	
	//映射LCD
	map_lcd = (int *)mmap(	NULL,
							800*480*4,
							PROT_READ|PROT_WRITE,
							MAP_SHARED,
							fd_lcd,
							0);
	if(map_lcd == MAP_FAILED)
	{
		perror("map LCD failed:");
		return -1;
	}
}

int fifo_init(){
    //判断文件是否存在
    int res =access("/tmp/fifo",F_OK);   
    if(res!=0){
       mkfifo("/tmp/fifo",0777);
    }
}
int lcd_uinit()
{
	//解除映射
	munmap(map_lcd,800*480*4);
	//关闭LCD的设备文件
	close(fd_lcd);
}

int ts_init(){
    //打开触摸屏的设备文件
	
	fd_ts = open("/dev/input/event0",O_RDWR);
	if(-1 == fd_ts)
	{
		perror("open ts failed :");
		return -1;
	}
    
}

int lcd_draw_bmp(int x_s,int y_s,char *pathname)
{
	//打开图片文件
	int fd_bmp;
	fd_bmp = open(pathname,O_RDWR);
	if(-1 == fd_bmp)
	{
		perror("open bmp failed:");
		return -1;
	}
	
	//读取文件的54字节数据信息
	char buf_head[54];
	
	read(fd_bmp,buf_head,sizeof(buf_head));
	
	//计算图片的宽度和高度
	int bmp_w,bmp_h;
	
	bmp_w = buf_head[18]|buf_head[19]<<8|buf_head[20]<<16|buf_head[21]<<24;
	bmp_h = buf_head[22]|buf_head[23]<<8|buf_head[24]<<16|buf_head[25]<<24;
	// printf("bmp_w=%d,bmp_h=%d\n",bmp_w,bmp_h);
	
	//计算被补充的无效字节的大小
	int n;
	
	if(bmp_w*3%4)
	{
		n = 4-bmp_w*3%4;
	}
	else
	{
		n = 0;
	}
	// printf("n=%d\n",n);
	
	//读取图片文件里的颜色数据
	char buf_bmp[bmp_w*bmp_h*3];
	int i;
	
	for(i=0;i<bmp_h;i++)
	{
		read(fd_bmp,&buf_bmp[bmp_w*3*i],bmp_w*3);
		lseek(fd_bmp,n,SEEK_CUR);
	}
	
	//关闭图片文件
	close(fd_bmp);
	
	//对读取的bmp的颜色数据进行ARGB整合
	int buf_lcd[bmp_w*bmp_h];
	
	for(i=0;i<bmp_w*bmp_h;i++)
	{
		//ARGB			A			R				G				B
		buf_lcd[i] = 0x00<<24|buf_bmp[i*3+2]<<16|buf_bmp[i*3+1]<<8|buf_bmp[i*3];
	}
	
	int x,y;
	
	int buf_lcd_swap[bmp_h][bmp_w];
	
	for(y=0;y<bmp_h;y++)
	{
		for(x=0;x<bmp_w;x++)
		{
			buf_lcd_swap[y][x] = buf_lcd[(bmp_h-1-y)*bmp_w+x];	
		}
	}
	
	//若x_s为-1，则计算x轴的居中显示位置，否则按照实际数值使用
	if(x_s == -1)
	{
		x_s = (800-bmp_w)/2;
	}
	
	//若y_s为-1，则计算y轴的居中显示位置，否则按照实际数值使用
	if(y_s == -1)
	{
		y_s = (480-bmp_h)/2;
	}
	
	for(y=0;y<bmp_h;y++)
	{
		for(x=0;x<bmp_w;x++)
		{
			*(map_lcd+(y+y_s)*800+x+x_s) = buf_lcd_swap[y][x];	
		}
	}
}

int ts_xy(){
    struct input_event ts;
	
	while(1)
	{
		//读取触摸屏的设备文件
		read(fd_ts,&ts,sizeof(ts));		//阻塞函数
		printf("type=%d,code=%d,value=%d\n",ts.type,ts.code,ts.value);
		
		if(ts.type==EV_ABS && ts.code==ABS_X)
		{
			//x = ts.value;			//蓝色
			x = ts.value*800/1024;	//黑色
			flag = 1;
		}
		
		if(ts.type==EV_ABS && ts.code==ABS_Y)
		{
			//y = ts.value;			//蓝色
			y = ts.value*480/600;	//黑色
		}
		
		if(ts.type==EV_ABS && ts.code==ABS_PRESSURE && ts.value==0)
		{			
			break;
		}
		else if(ts.type==EV_KEY && ts.code==BTN_TOUCH && ts.value==0)
		{			
			break;
		}
		if(ts.type==1 && ts.code == 330 && ts.value == 0){
			if(ts.type==0 && ts.code==0 && ts.value ==0){
				flag = -1;
			}
		}
	}
	
	// printf("(%d,%d)\n",x,y);

}


void liufu(){
    x=0;
    y=0;
}
void pic_init(){
	int i,j;
	for(i=0;i<480;i++){
        for(j=0;j<800;j++){
            *(map_lcd+i*800+j) =0x00000000;
        }
    }
   lcd_draw_bmp(81*0,480-71,"zt.bmp");
   lcd_draw_bmp(81*1,480-71,"xys.bmp");
   lcd_draw_bmp(81*2,480-71,"sys.bmp");
   lcd_draw_bmp(81*3,480-71,"sys.bmp");
   lcd_draw_bmp(81*4,480-71,"sys.bmp");
}
void *func(){
	system("mplayer -slave -quiet -input file=/tmp/fifo -geometry 0:0 -zoom -x 800 -y 400 2.avi &");
	int num;
	while(1){
        if(x>0 && y>0){               
                num = (x/81)+1;
                if(num==1){                  
                    write(fifo,"pause\n",strlen("pause\n"));
                    liufu();
                }else if(num==2){
					fu = (fu+1)%n; 				
					sprintf(name,"mplayer -slave -quiet -input file=/tmp/fifo -geometry 0:0 -zoom -x 800 -y 400 %s &",namelist[fu]->d_name);
					system("killall -9 mplayer");
					system(name);
					liufu();
  
                }else if(num==3){
                   	fu = (fu-1+n)%n; 				
					sprintf(name,"mplayer -slave -quiet -input file=/tmp/fifo -geometry 0:0 -zoom -x 800 -y 400 %s &",namelist[fu]->d_name);
					system("killall -9 mplayer");
					system(name);
					liufu();
                }else if(num==4){
                    write(fifo,"seek +5\n",strlen("seek +5\n"));
					liufu();					
                }else if(num==5){
                    write(fifo,"volume -5\n",strlen("volume -5\n"));
                    liufu();
                // }else if(num==6){
                //     write(fifo,"seek +5\n",strlen("seek +5\n"));
                //     liufu();
                // }else if(num==7){
                //     write(fifo,"seek +5\n",strlen("seek +5\n"));
                //     liufu();
                // }
            
				}
   
        }
    }
}


int main(int argc,char *argv[])	//./xxx xxx(参数1) xxx(参数2) ...
{
	
	
	lcd_init();
	pic_init();
    ts_init();
    fifo_init();

   
	
	int z;
	//n  代表的是myfilter函数的检测的avi个数
	n=scandir(argv[1],&namelist,myfilter_mp3,alphasort);
	printf("n=%d\n",n);
	printf("current song is 2.avi!\n");
    for(z=0;z<n;z++){
        printf("namelist[%d] %s\n",z,namelist[z%n]->d_name);
    }
    

    fifo = open("/tmp/fifo",O_RDWR);
    if(fifo<0){
        printf("fifo open erro");
    }


	pthread_t pid;
	pthread_create(&pid,NULL,func,NULL);
	while(1){
        ts_xy();
    }



    close(fd_ts);
	lcd_uinit();
	

	return 0;
}